package com.hssoftvn.android.apps.callmessmoneycontroller.modules;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

import com.hssoftvn.android.apps.callmessmoneycontroller.util.SUtils;

public class TinyLocationUtils{	
	
	private static LocationManager mLocMan = null;
	private static Location mLoc = null;
	private static boolean mIsLocationReady = false;
	public static boolean isNewLocationReady() {
		return mIsLocationReady;
	}

	protected static TinyLocationListener mTinyLocationListener = null;
	protected static TinyLocationReceiver mTinyLocationReceiver  = null;
	
	private static String PROVIDER_REQUEST_GPS_WITH_ACCURATE_RESULT = LocationManager.GPS_PROVIDER;
	private static String PROVIDER_REQUEST_NETWORD_BASING_ON_CELL_TOWER = LocationManager.NETWORK_PROVIDER;	
	private static String PROVIDER_GET_RESULT_ONLY_DONT_REQUEST = LocationManager.PASSIVE_PROVIDER;
	private static int MIN_INTERVAL_UPDATE_TIME_IN_MILISEC = 10000;//Update every 10sec
	private static int MIN_INTERVAL_UPDATE_DISTANCE_IN_METERS = 50;//evry 50met
	private static String INTENT_UPDATE_LOCATION = "com.hssoftvn.android.TINY_ACTION_UPDATE_LOCATION"; 
	
	
	public static void init(){
		mLocMan = (LocationManager) SUtils.getAppContext().getSystemService(Context.LOCATION_SERVICE);
		mTinyLocationListener = new TinyLocationListener();
		mTinyLocationReceiver = new TinyLocationReceiver();
		mLoc = mLocMan.getLastKnownLocation(PROVIDER_GET_RESULT_ONLY_DONT_REQUEST);
		IntentFilter filter = new IntentFilter(INTENT_UPDATE_LOCATION);
		SUtils.getAppContext().registerReceiver(mTinyLocationReceiver, filter);
	}
	public static void terminate(){
		try {
			mLocMan = null;
			mTinyLocationListener = null;
			SUtils.getAppContext().unregisterReceiver(mTinyLocationReceiver);
			mTinyLocationReceiver = null;
			mLoc = null;
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	public static Location getLocation(){
		if (!mIsLocationReady) {
			mLoc = mLocMan.getLastKnownLocation(PROVIDER_GET_RESULT_ONLY_DONT_REQUEST);
			if (mLoc == null)
				mLoc = mLocMan.getLastKnownLocation(PROVIDER_REQUEST_GPS_WITH_ACCURATE_RESULT);
			if (mLoc == null)
				mLoc = mLocMan.getLastKnownLocation(PROVIDER_REQUEST_NETWORD_BASING_ON_CELL_TOWER);
		}
		return mLoc;
	}
	 
	/*
	 *  Use this method requestLocationUpdate to requests for location
	 *  Use getLocation() to obtain the location result
	 *  	+ if isNewLocationReady
	 *  		- use the new location from location request
	 *  	+ no: 
	 *  		- use the latest requested location result
	 *  Don't forget to call init() first of all
	 */
	public static void requestLocationUpdate(){
		mIsLocationReady = false;
		
		Thread threadRequest = new Thread( new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//Looper.prepare();
				mIsLocationReady = false;
				Log.d(SUtils.TAG, "We have to update location.....");
				mLocMan.requestLocationUpdates(
						PROVIDER_REQUEST_GPS_WITH_ACCURATE_RESULT,
						//PROVIDER_REQUEST_NETWORD_BASING_ON_CELL_TOWER,
						MIN_INTERVAL_UPDATE_TIME_IN_MILISEC,
						MIN_INTERVAL_UPDATE_DISTANCE_IN_METERS,
						mTinyLocationListener
						);
				//Looper.loop();
			}
		});
		threadRequest.run();
	}
	static class TinyLocationListener implements LocationListener{

		@Override
		public void onLocationChanged(Location loc) {
			// TODO Auto-generated method stub
			Intent i = new Intent();
			i.setAction(INTENT_UPDATE_LOCATION);
			i.putExtra("latitude", loc.getLatitude()); // horizontal value : from EAST to WEST 
			i.putExtra("longitude", loc.getLongitude()); // vertical value : from NORTH to SOUTH
			if (loc.hasAltitude()){
				i.putExtra("altitude", loc.getAltitude()); // height value compared to the ground
			}
			mLoc = loc;
			mIsLocationReady = true;
			Log.d(SUtils.TAG, "We have the location update");
			//using sending broadcast and using an broadcastreceiver to handle
			SUtils.getAppContext().sendBroadcast(i);			
		}

		@Override
		public void onProviderDisabled(String arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onProviderEnabled(String arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
			// TODO Auto-generated method stub
			
		}
	}
	
	static class TinyLocationReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context ctx, Intent i) {
			// TODO Auto-generated method stub
			if (i.getAction().equals(INTENT_UPDATE_LOCATION)){
				String data = "Location data: (";
				if (!i.getExtras().isEmpty()){
					data += i.getExtras().getDouble("latitude")+", ";
					data += i.getExtras().getDouble("longitude")+"";
					if (i.hasExtra("altitude"))
						data += ", " + i.getExtras().getDouble("altitude")+"";
					data += ")";
				}
				SUtils.showDialogMessage("Warning", "Please implement the method!\n" + data);
			}
		}
		
	}
	
}
